Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CL] Changes from audit results(1/2) #5568

Merged
merged 10 commits into from
Jun 20, 2023
Merged

[CL] Changes from audit results(1/2) #5568

merged 10 commits into from
Jun 20, 2023

Conversation

mattverse
Copy link
Member

Closes: #XXX

What is the purpose of the change

These are changes from the audit results.

Testing and Verifying

Ensured that existing test cases pass

Documentation and Release Note

  • Does this pull request introduce a new feature or user-facing behavior changes?
  • Changelog entry added to Unreleased section of CHANGELOG.md?

Where is the change documented?

  • Specification (x/{module}/README.md)
  • Osmosis documentation site
  • Code comments?
  • N/A

@mattverse mattverse added V:state/compatible/no_backport State machine compatible PR, depends on prior breaks A:no-changelog labels Jun 19, 2023
@github-actions github-actions bot added C:simulator Edits simulator or simulations C:x/concentrated-liquidity C:x/gamm Changes, features and bugs related to the gamm module. C:x/incentives C:x/mint C:x/superfluid C:x/twap Changes to the twap module labels Jun 19, 2023
@@ -294,7 +294,7 @@ func (accum *AccumulatorObject) UpdatePosition(name string, numShares sdk.Dec) e
// All intervalAccumulationPerShare DecCoin value must be non-negative. They must also be a superset of the
// old accumulator value associated with the position.
func (accum *AccumulatorObject) UpdatePositionIntervalAccumulation(name string, numShares sdk.Dec, intervalAccumulationPerShare sdk.DecCoins) error {
if numShares.Equal(sdk.ZeroDec()) {
if numShares.IsZero() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using IsZero directly avoids creating and using a new sdk.Dec object

@@ -1163,7 +1163,7 @@ func (suite *AccumTestSuite) TestGetPositionSize() {
// Get position size from valid address (or from nonexistant if address does not exist)
positionSize, err := curAccum.GetPositionSize(positionName)

if tc.changedShares.GT(sdk.ZeroDec()) {
if tc.changedShares.IsPositive() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto for GT(sdk.ZeroDec) or LT(sdk.ZeroDec), using IsPositive or IsNegative methods avoid creating unnecessasry sdk.Dec object


// If there is no share to be incentivized for the current uptime accumulator, we leave it unchanged
if qualifyingLiquidity.LT(sdk.OneDec()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change mainly is from here, right now, we are entering loop checking if qualifyingLiquidity.LT(sdk.OneDec()) and then continue checking this every iteration.
This can be refactored into simply having this check before the for iteration

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM

err = k.ensurePositionOwner(ctx, sender, position.PoolId, positionId)
if err != nil {
return sdk.Coins{}, sdk.Coins{}, err
if sender.String() != position.Address {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directly checking this instead of using ensurePositionOwner allows us to save unnecessary iteration over all positions in the pool

@@ -321,21 +321,19 @@ func (k Keeper) addToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId
return 0, sdk.Int{}, sdk.Int{}, types.PositionSuperfluidStakedError{PositionId: position.PositionId}
}

// Withdraw full position.
amount0Withdrawn, amount1Withdrawn, err := k.WithdrawPosition(ctx, owner, positionId, position.Liquidity)
positions, err := k.GetAllPositionIdsForPoolId(ctx, types.PositionPrefix, position.PoolId)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this check and checking if this would be the last position before the actual WithdrawPosition rather than doing this after calling WithdrawPosition allows us to save computation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait isn't this linear in the number of position ID's for a pool? Thats way too expensive to run on addToPosition?

Copy link
Member

@ValarDragon ValarDragon Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah actually removing my approve, I think we have to revert this lp.go change before its safe to merge

Good to merge after this is reverted

Comment on lines -666 to -667
err = concentratedLiquidityKeeper.EnsurePositionOwner(s.Ctx, owner, config.poolId, config.positionId)
s.Require().Error(err, types.NotPositionOwnerError{PositionId: config.positionId, Address: owner.String()})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensurePositionOwner method is now deleted, nor do we need this check in this test case

Comment on lines -102 to -117
func (k Keeper) ensurePositionOwner(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, positionId uint64) error {
isOwner := k.isPositionOwner(ctx, sender, poolId, positionId)
if !isOwner {
return types.NotPositionOwnerError{
PositionId: positionId,
Address: sender.String(),
}
}
return nil
}

// isPositionOwner returns true if the given positionId is owned by the given sender inside the given pool.
func (k Keeper) isPositionOwner(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, positionId uint64) bool {
return ctx.KVStore(k.storeKey).Has(types.KeyAddressPoolIdPositionId(sender, poolId, positionId))
}

Copy link
Member Author

@mattverse mattverse Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not used any more, thus deletion

@@ -410,103 +410,6 @@ type positionOwnershipTest struct {
poolId uint64
}

func (s *KeeperTestSuite) runIsPositionOwnerTest(test positionOwnershipTest) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method that was being tested is now deleted thus test is removed as well

Comment on lines +295 to +300
// defense in depth
// this should never happen in practice since gauge passed in should always be an active gauge.
if remainEpochs == uint64(0) {
return nil, fmt.Errorf("gauge with id of %d is not active", gauge.Id)
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should never happen in practice, but if it does, this can lead to chain halt since this would lead to division by zero(=panic) in Begin block, which can potentially lead to chain halt. Thus adding defense in depth

Comment on lines -478 to -507
swapState.amountSpecifiedRemaining = swapState.amountSpecifiedRemaining.SubMut(amountOut)
swapState.amountCalculated = swapState.amountCalculated.AddMut(amountIn.Add(spreadRewardChargeTotal))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, I personally find it easier to see whats going on with the equal signs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's bring back the equal signs

@@ -25,7 +25,7 @@ func CalcExitPool(ctx sdk.Context, pool types.CFMMPoolI, exitingShares sdk.Int,
var refundedShares sdk.Dec
if !exitFee.IsZero() {
// exitingShares * (1 - exit fee)
oneSubExitFee := sdk.OneDec().SubMut(exitFee)
oneSubExitFee := sdk.OneDec().Sub(exitFee)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not actually a bug (as oneDec is a new copy), but LGTM.

Anyways not on a hot path

Copy link
Member

@ValarDragon ValarDragon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes LGTM

Though not sure I agree with some of the removing = for already mutative ops.

The changing things to IsZero / IsPositive is great!

Comment on lines +295 to +299
// defense in depth
// this should never happen in practice since gauge passed in should always be an active gauge.
if remainEpochs == uint64(0) {
return nil, fmt.Errorf("gauge with id of %d is not active", gauge.Id)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also be adding a check in validate basic that NumEpochsPaidOver can't be 0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@p0mvn which validate basic are you referring to ?

Copy link
Member

@p0mvn p0mvn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Would like to bump up Dev's concern about getting all positions in AddToPosition prior to merge

@@ -321,21 +321,19 @@ func (k Keeper) addToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId
return 0, sdk.Int{}, sdk.Int{}, types.PositionSuperfluidStakedError{PositionId: position.PositionId}
}

// Withdraw full position.
amount0Withdrawn, amount1Withdrawn, err := k.WithdrawPosition(ctx, owner, positionId, position.Liquidity)
positions, err := k.GetAllPositionIdsForPoolId(ctx, types.PositionPrefix, position.PoolId)
Copy link
Member

@ValarDragon ValarDragon Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah actually removing my approve, I think we have to revert this lp.go change before its safe to merge

Good to merge after this is reverted

mattverse and others added 9 commits June 20, 2023 14:45
* repro panic trigger and fix bound check

* fix comments
)

Closes: #XXX

## What is the purpose of the change

Related to: #5550

Documenting latest decisions around tick and price conversions

## Testing and Verifying

This change is a trivial rework / code cleanup without any test coverage.

## Documentation and Release Note

  - [ ] Does this pull request introduce a new feature or user-facing behavior changes?
  - [ ] Changelog entry added to `Unreleased` section of `CHANGELOG.md`?

Where is the change documented? 
  - [ ] Specification (`x/{module}/README.md`)
  - [ ] Osmosis documentation site
  - [ ] Code comments?
  - [ ] N/A
Closes: #XXX

## What is the purpose of the change

The following PR introduces a functional test that:
- Creates every type of balancer position that can be created
  - Bonded superfluid
  - Unbonded superfluid (locked)
  - Unbonded superfluid (unlocking)
  - Vanilla lock (locked)
  - Vanilla lock (unlocking)
  - No lock
- It then migrates each position, asserting invariants after each position is migrated
- Finally, an overall invariant is run after all positions have been migrated, asserting that all funds are accounted for in some way

The next PR subsequent to this will be adding randomization to the inputs in order to make the test non deterministic. 

## Testing and Verifying

Functional test above added

## Documentation and Release Note

  - [ ] Does this pull request introduce a new feature or user-facing behavior changes?
  - [ ] Changelog entry added to `Unreleased` section of `CHANGELOG.md`?

Where is the change documented? 
  - [ ] Specification (`x/{module}/README.md`)
  - [ ] Osmosis documentation site
  - [ ] Code comments?
  - [ ] N/A
… <> sqrt price (#5541)

Closes: #5516

> **Note to reviewer:** the only real state machine change is in `tick.go` and heavily mirrors @ValarDragon's PR here: #5522 
> The rest of the changes are related to function renames/test refactors.

## What is the purpose of the change

This PR expands on #5522 and updates all price to tick conversions to use SqrtPriceToTick instead.

## Testing and Verifying

The new function is tested in `math/tick_test.go`

The original attack vector is also converted into an edge case test in `position_test.go`

## Documentation and Release Note

  - [ ] Does this pull request introduce a new feature or user-facing behavior changes?
  - [ ] Changelog entry added to `Unreleased` section of `CHANGELOG.md`?

Where is the change documented? 
  - [ ] Specification (`x/{module}/README.md`)
  - [ ] Osmosis documentation site
  - [ ] Code comments?
  - [ ] N/A
@mattverse
Copy link
Member Author

lp.go has been reverted to original state, planning to merge this upon seeing CI pass

@mattverse
Copy link
Member Author

Oh I can't merge it unless a third reviewer lifts the existing requested change review

@ValarDragon ValarDragon merged commit 0cea7aa into main Jun 20, 2023
@ValarDragon ValarDragon deleted the mattverse/informal branch June 20, 2023 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A:no-changelog C:simulator Edits simulator or simulations C:x/concentrated-liquidity C:x/gamm Changes, features and bugs related to the gamm module. C:x/incentives C:x/mint C:x/superfluid C:x/twap Changes to the twap module V:state/compatible/no_backport State machine compatible PR, depends on prior breaks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants